package main

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/go-redis/redis"
	_ "github.com/go-sql-driver/mysql"
	"github.com/yyangl/yoyo/application"
	"github.com/yyangl/yoyo/proto"
	"github.com/yyangl/yoyo/registry"
	"github.com/yyangl/yoyo/registry/etcd"
	"github.com/yyangl/yoyo/respository"
	conf "github.com/yyangl/yoyo/srv/admin/conf"
	"github.com/yyangl/yoyo/utils"
)

type AdminServer struct {
	application.Server
	addr  string
	name  string
	db    *sql.DB
	redis *redis.Client
}

func (s *AdminServer) PromisesById(ctx context.Context, req *proto.PromisesReq) (*proto.PromisesRep, error) {
	fmt.Println("%s", ctx.Value("request-id"))
	res, err := respository.GetPromiseByAdminID(s, req.Uid)
	if err != nil {
		return nil, err
	}
	var promises []*proto.PromisesRep_Promise
	if res == nil {
		return &proto.PromisesRep{
			Promises: promises,
		}, nil
	}
	for _, item := range res {
		var promise proto.PromisesRep_Promise
		promise.Path = item.Path
		promise.Value = int32(item.Value)
	}
	return &proto.PromisesRep{
		Promises: promises,
	}, nil
}

func (s *AdminServer) Menus(ctx context.Context, req *proto.MenusReq) (*proto.MenuResp, error) {
	res, err := respository.GetMenus(s, req.Uid)
	if err != nil {
		return nil, err
	}
	fmt.Printf("%v", res)
	var menus []*proto.MenuResp_Menu
	if res == nil {
		return &proto.MenuResp{
			Menus: menus,
		}, nil
	}
	for _, v := range res {
		var menu proto.MenuResp_Menu
		menu.Type = int32(v.Type)
		menu.Pid = v.Pid
		menu.Path = v.Path
		menu.Hidden = v.Hidden == 1
		menu.Level = int32(v.Level)
		menu.Name = v.Name
		menus = append(menus, &menu)
	}
	return &proto.MenuResp{
		Menus: menus,
	}, nil
}

func (s *AdminServer) Db() *sql.DB {
	return s.db
}

func (s *AdminServer) Redis() *redis.Client {
	return s.redis
}

func (s *AdminServer) TTL() int64 {
	return 5
}

func (s *AdminServer) Name() string {
	return s.name
}

func (s *AdminServer) Addr() string {
	return s.addr
}

func (s *AdminServer) Login(ctx context.Context, req *proto.LoginReq) (*proto.LoginRep, error) {
	fmt.Printf("ctx value is %v", ctx.Value("a"))
	token, err := respository.CheckAccount(s.db, req.Account, req.Passwd)
	if err != nil {
		return nil, err
	}
	rep := &proto.LoginRep{
		Token: token,
	}
	return rep, nil
}

func (s *AdminServer) Reg(ctx context.Context, req *proto.CreateReq) (*proto.CreateRep, error) {
	err := respository.CreateAccount(s.db, req.Account, req.Password, req.Name)
	if err != nil {
		return nil, err
	}
	rep := &proto.CreateRep{
		Msg: "创建成功",
	}
	return rep, nil
}

func main() {
	config := &conf.Config{}
	err := utils.LoadConfig("./admin.json", &config)
	if err != nil {
		fmt.Printf("config error. err = %v\n", err)
		return
	}
	dns := config.DbConfig.GetDns()
	db, err := sql.Open("mysql", dns)
	if err != nil {
		fmt.Printf("config sql err.err = %s", err.Error())
		return
	}
	if err = db.Ping(); err != nil {
		fmt.Printf("open database err.err = %s", err.Error())
		return
	}
	rds := redis.NewClient(&redis.Options{
		Addr:     "127.0.0.1:6379",
		DB:       1,
		Password: "",
	})
	srv := &AdminServer{
		addr:  config.Addr,
		name:  config.Name,
		db:    db,
		redis: rds,
	}
	register, err := etcd.NewEtcdRegister(registry.DefaultAddr)
	if err != nil {
		fmt.Printf("etcd error. err = %v\n", err)
		return
	}
	srv.SetRegister(register)
	err = srv.Register()
	if err != nil {
		fmt.Printf("service register error. err = %v\n", err)
		return
	}
	proto.RegisterAdminServiceServer(srv.GetServer(), srv)
	if err = srv.Run(srv); err != nil {
		fmt.Printf("service run error. err = %v\n", err)
	}
}
